package com.graphsql.gamesdk.base;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.apache.http.NameValuePair;

import com.graphsql.gamesdk.R;
import com.graphsql.gamesdk.network.HttpConnecter;
import com.graphsql.gamesdk.util.JsonUtils;
import com.graphsql.gamesdk.util.LogDebugger;
import com.graphsql.gamesdk.util.MD5Util;
import com.graphsql.gamesdk.util.StringUtils;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.DialogInterface.OnClickListener;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;

public class BaseFragment extends Fragment {
	private static final String TAG = "BaseFragment";

	public static final int SHOW_PROGRESS = 0;

	public static final int REFRESH = 1;

	public static final int SHOW_DIALOG = 2;

	public static final int REMOVE_PROGRESS = 3;

	public static final int NETWORK_ERROR = 4;

	/**
	 * some times, only need to refresh listview items
	 */
	public static final int REFRESH_LIST = 5;

	public static final int INFO = 100;

	public static final int ERROR = 200;

	public static final int DRAWABLE_ICON = 0;

	public static final int DRAWABLE_BG = 1;

	private static Resources mResources;

	private static ExecutorService mThreadPool = Executors
			.newFixedThreadPool(10);

	private RelativeLayout mShowPlant;
	
	private ProgressBar mShowBar;
	
	private TextView mShowText;
	
	private ImageView mShowImg;	

	private volatile int activeThreadNum = 0;

	protected boolean runningFlag = true;

	private boolean destroyFlag = false;

	private boolean showDialogFlag = false;

	protected boolean downloadJobFlag = false;

	private String mDialogTitle;

	private String mDialogMessage;

	private static String mError = "Error";

	private String mClassName;

	private int mLayoutResId;
	
	protected LayoutInflater mLayoutInflater;
	
	public RelativeLayout rootView;
	
	public Handler mHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			if (destroyFlag) {
				return;
			}
			switch (msg.what) {
			case SHOW_PROGRESS:
				if (mShowPlant!=null) {
					mShowPlant.setVisibility(View.VISIBLE);
					mShowBar.setVisibility(View.VISIBLE);
					mShowImg.setVisibility(View.INVISIBLE);
					mShowText.setText(R.string.gs_string_wait);
				}
				break;
			case REMOVE_PROGRESS:
				if (mShowPlant!=null){
					mHandler.removeMessages(SHOW_PROGRESS);
					mShowPlant.setVisibility(View.INVISIBLE);
					mShowBar.setVisibility(View.INVISIBLE);
				}
				if(activeThreadNum <= 0) {
					activeThreadNum = 0;
				}
				break;
			case NETWORK_ERROR:
				if (mShowPlant!=null) {
					mShowPlant.setVisibility(View.VISIBLE);
					mShowBar.setVisibility(View.INVISIBLE);
					mShowImg.setVisibility(View.VISIBLE);
					mShowText.setText(R.string.gs_string_wait_error);
				}
				break;
			case REFRESH:
				onRefresh();
				break;
			case REFRESH_LIST:
				onRefreshList();
				break;
			case SHOW_DIALOG:
				if (showDialogFlag) {
					return;
				}
				showDialogFlag = true;
				DialogInfo info = (DialogInfo) msg.obj;
				if (info != null) {
					new AlertDialog.Builder(BaseFragment.this.getActivity())
							.setIcon(android.R.drawable.ic_dialog_info)
							.setTitle(info.title)
							.setMessage(info.message)
							.setOnCancelListener(new OnCancelListener() {
								@Override
								public void onCancel(DialogInterface dialog) {
									// TODO Auto-generated method stub
									showDialogFlag = false;
								}
							})
							.setPositiveButton(android.R.string.ok,
									new OnClickListener() {
										@Override
										public void onClick(
												DialogInterface dialog,
												int which) {
											showDialogFlag = false;
										}
									}).show();
				} else {
					showAlertDialog(msg.arg1);
				}
				break;
			default:
				onHandleMessage(msg);
				break;
			}
		}
	};

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
//		LogDebugger.info(TAG, "onCreate " + mClassName);
		if (mResources == null) {
			mResources = getResources();
		}
	}
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		super.onCreateView(inflater, container, savedInstanceState);
		mClassName = getClass().getSimpleName();
		LogDebugger.info(TAG, "onCreateView " + mClassName);
		int end = mClassName.length() - 8;
		mLayoutResId = mResources.getIdentifier(
				""+ mClassName.toLowerCase(Locale.ENGLISH).substring(0,
								end), "layout",this.getActivity().getPackageName());
		mLayoutInflater = inflater;
		rootView = (RelativeLayout)inflater.inflate(mLayoutResId, container, false);
		mShowPlant = (RelativeLayout)inflater.inflate(R.layout.gs_showlayout, container, false);
		mShowBar = (ProgressBar)mShowPlant.findViewById(R.id.gs_show_bar);
		mShowImg = (ImageView)mShowPlant.findViewById(R.id.gs_show_img);
		mShowText = (TextView)mShowPlant.findViewById(R.id.gs_show_txt);
		RelativeLayout.LayoutParams  params = new RelativeLayout.LayoutParams(mShowPlant.getLayoutParams());
		params.addRule(RelativeLayout.CENTER_IN_PARENT);
		mShowPlant.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				if(mShowBar.getVisibility()==View.INVISIBLE){
					onPrepareData();
				}
			}
		});
		mShowPlant.setVisibility(View.INVISIBLE);
		rootView.addView(mShowPlant, params);
		init();
		return rootView;
	}

	protected void handleFuncClick() {
	};
	
	@Override
	public void onStart() {
		super.onStart();
		runningFlag = true;
//		onPrepareData();//在FragmentActivity中会全部创建好所有的子Fragment
		downloadJobFlag = false;
		LogDebugger.info(TAG, "onStart " + mClassName);
	}

	@Override
	public void onResume() {
		super.onResume();
		showDialogFlag = false;
		runningFlag = true;
		downloadJobFlag = false;
		LogDebugger.info(TAG, "onResume " + mClassName);
	}

	@Override
	public void onPause() {
		super.onPause();
		runningFlag = false;
		LogDebugger.info(TAG, "onPause " + mClassName);
	}

	@Override
	public void onStop() {
		super.onStop();
		runningFlag = false;
		LogDebugger.info(TAG, "onStop " + mClassName);
	}
	@Override
	public void onDestroyView() {
		super.onDestroyView();
		if(rootView!=null){
			rootView.removeAllViews();
			rootView = null;
		}
		LogDebugger.info(TAG, "onDestroyView " + mClassName);
	}
	@Override
	public void onDestroy() {
		super.onDestroy();
		destroyFlag = true;
		LogDebugger.info(TAG, "onDestroy " + mClassName);
		System.gc();
	}
	

	protected void showAlertDialog(int id) {
		switch (id) {
		case ERROR:
			new AlertDialog.Builder(BaseFragment.this.getActivity())
					.setIcon(getDrawable(android.R.drawable.ic_dialog_alert))
					.setMessage(mError)
					.setOnCancelListener(new OnCancelListener() {
						@Override
						public void onCancel(DialogInterface dialog) {
							showDialogFlag = false;
						}
					})
					.setPositiveButton(android.R.string.ok,
							new OnClickListener() {
								@Override
								public void onClick(DialogInterface dialog,
										int which) {
									showDialogFlag = false;
								}
							}).create().show();
			break;
		case INFO:
			new AlertDialog.Builder(BaseFragment.this.getActivity())
					.setIcon(android.R.drawable.ic_dialog_info)
					.setTitle(mDialogTitle)
					.setMessage(mDialogMessage)
					.setOnCancelListener(new OnCancelListener() {
						@Override
						public void onCancel(DialogInterface dialog) {
							showDialogFlag = false;
						}
					})
					.setPositiveButton(android.R.string.ok,
							new OnClickListener() {
								@Override
								public void onClick(DialogInterface dialog,
										int which) {
									showDialogFlag = false;
								}
							}).create().show();
			break;
		default:
			new AlertDialog.Builder(BaseFragment.this.getActivity())
					.setIcon(getDrawable(android.R.drawable.ic_dialog_alert))
					.setTitle("No Such Dialog")
					.setMessage("Oops")
					.setOnCancelListener(new OnCancelListener() {
						@Override
						public void onCancel(DialogInterface dialog) {
							showDialogFlag = false;
						}
					})
					.setPositiveButton(android.R.string.ok,
							new OnClickListener() {
								@Override
								public void onClick(DialogInterface dialog,
										int which) {
									showDialogFlag = false;
								}
							}).create().show();
			break;

		}

	}

	protected void init() {
	}

	public void onPrepareData() {
	}

	protected void onRefresh() {
	}

	protected void onRefreshList() {
	}

	protected void onHandleMessage(Message msg) {
	}

	protected void doAsync(Runnable command) {
		mThreadPool.execute(command);
	}

	protected String[] getStringArray(int id) {
		return mResources.getStringArray(id);
	}

	protected Drawable getDrawable(int id) {
		return mResources.getDrawable(id);
	}


	protected final void sendMessage(int what) {
		mHandler.sendMessage(mHandler.obtainMessage(what));
	}

	protected final void sendMessage(int what, int arg1, int arg2) {
		mHandler.sendMessage(mHandler.obtainMessage(what, arg1, arg2));
	}

	protected final void sendMessageDelayed(int what, long delayMillis) {
		mHandler.sendMessageDelayed(mHandler.obtainMessage(what), delayMillis);
	}

	protected final void sendMessageDelayed(int what, int arg1, int arg2,
			long delayMillis) {
		mHandler.sendMessageDelayed(mHandler.obtainMessage(what, arg1, arg2),
				delayMillis);
	}

	protected final void sendMessage(int what, Object obj) {
		mHandler.sendMessage(mHandler.obtainMessage(what, obj));
	}
	
	protected final void sendMessage(int what, int arg1, int arg2, Object obj) {
		mHandler.sendMessage(mHandler.obtainMessage(what, arg1, arg2, obj));
	}

	protected final void removeMessages(int what) {
		mHandler.removeMessages(what);
	}
	/**
	 * uri request thread.
	 * 
	 */
	public class Request implements Runnable {

        private String uri;
        private String method = "get";
        private ArrayList<NameValuePair> formparams = new ArrayList<NameValuePair>();
        private List<File> attachments = new ArrayList<File>();
        private boolean cancelable;
        private long delayMillis;
        private boolean needProgress = true;

        public Request(String uri) {
            this(uri, "get", null);
        }
        public Request(String uri,boolean needProgress) {
            this(uri, "get", null,null,true,0L,needProgress);
        }

        public Request(String uri, String method,
                ArrayList<NameValuePair> formparams) {
            this(uri, method, formparams,null, true);
        }
        public Request(String uri, String method,
                ArrayList<NameValuePair> formparams,List<File> attachments) {
            this(uri, method, formparams, attachments,true);
        }

        public Request(String uri, String method,
                ArrayList<NameValuePair> formparams,List<File> attachments, boolean cancelable) {
            this(uri, method, formparams,attachments, cancelable, 0L,true);
        }

        public Request(String uri, String method,
                ArrayList<NameValuePair> formparams, List<File> attachments,boolean cancelable,
                long delayMillis,boolean needProgress) {
            this.uri = uri;
            this.method = method;
            this.formparams = formparams;
            this.attachments = attachments;
            this.cancelable = cancelable;
            this.delayMillis = delayMillis;
            this.needProgress = needProgress;
        }

//      protected void onSuccess(String json) {
//      }
//
//      protected void onFailure(String json) {
//          sendMessage(SHOW_DIALOG, INFO, ERROR);
//      }

         protected void onSuccess(Map<?, ?> map) {
         }
        
         protected void onFailure(Map<?, ?> map) {
         sendMessage(SHOW_DIALOG, INFO, ERROR);
         }

        @Override
        public void run() {

            if (!runningFlag) {
                return;
            }

            if (cancelable) {
                if(needProgress)sendMessageDelayed(SHOW_PROGRESS, 100L);
            } else {
                if(needProgress)sendMessageDelayed(SHOW_PROGRESS, 1, 1, 100L);
            }

            activeThreadNum++;

            if (delayMillis > 0) {
                try {
                    Thread.sleep(delayMillis);
                } catch (InterruptedException ie) {
                }
            }
    		System.out.println("Request "+getFullUri(uri,formparams));
            String fileName = MD5Util.md5(getFullUri(uri,formparams));
            String response = null;
            try {
                if (method.equals("get")) {
                    response = HttpConnecter.get(uri);
                } else if (method.equals("post")) {
                    response = HttpConnecter.post(uri, formparams);
                }
            } catch (Exception e) {
                response = null;
                LogDebugger.error(TAG, e.toString());
            }

            if (response!=null&&response.startsWith("{") && response.endsWith("}")) {
                 Map<?, ?> map;
                 map = JsonUtils.bindDataToModel(response);
                 if(map!=null){
                	 String status = (String) map.get("status");
                     mDialogMessage = (String) map.get("msg");
                     if (StringUtils.isNull(status)==false&&status.startsWith("true")) {
                         if (runningFlag) {
                             onSuccess(map);
                         }
                     } else {
                         if (runningFlag) {
                             onFailure(map);
                         }
                     }
                 }else{
                	 onFailure(null);
                 }
                 if(needProgress)sendMessageDelayed(REMOVE_PROGRESS,200L);
            } else {
                if (runningFlag) {
                    if(needProgress){
                    	sendMessageDelayed(NETWORK_ERROR,200L);
                    }else{
                         onFailure(null);
                    }
                }
            }
            activeThreadNum--;
        }
    }
	public String getFullUri(String baseUri ,ArrayList<NameValuePair> formparams){
        String fullUri = baseUri;
        if(formparams!=null&&formparams.size()>0){
            fullUri =fullUri+"?";
            for(int i=0;i<formparams.size();i++){
                if(i!=0)fullUri = fullUri+"&";
                NameValuePair value = formparams.get(i);
                fullUri +=value.getName()+"="+value.getValue();
            }
        }
        return fullUri;
    }

	public class DialogInfo {

		public String title;
		public String message;

		public DialogInfo(String title, String message) {
			this.title = title;
			this.message = message;
		}
	}
	
	
}
